﻿namespace IntellectShop.Web2.Hardware.Controllers
{
	using System;
	using System.Collections.Generic;
	using System.IO;
	using System.Linq;
	using System.Text;
	using System.Web;
	using System.Web.Mvc;
	using System.Xml;
	using IntellectShop.Common;
	using IntellectShop.Web2.Hardware.ViewModels;

	[IntellectShop.Web2.Hardware.Code.NoCache]
	[IntellectShop.Web2.Hardware.Code.HandleErrorWithELMAH]
	[ValidateInputAttribute(false)]
	public class HardwareController : Controller
	{
		public ActionResult Browse(string categoryID)
		{
			int id = Int32.Parse(categoryID);
			Common.Category category = Common.Category.RetrieveByID(id);
			if (category == null)
			{
				throw new HttpException(404, "Page not found");
			}

			HardwareTagedViewModel model = new HardwareTagedViewModel();
			model.HardwareTagged = new Dictionary<string, IEnumerable<Common.Hardware>>();
			model.Category = category;

			List<Common.Hardware> hardwares = Common.Hardware.RetrieveByCategoryID(id);
			List<Common.Hardware> alreadyAddedHardwares = new List<Common.Hardware>();

			Common.TagsSet tagsSet = Common.TagsSet.GetFavoritesTags(hardwares);
			tagsSet.Add(String.Empty);
			foreach (string tag in tagsSet)
			{
				IEnumerable<Common.Hardware> selectedHardwares;
				if (!String.IsNullOrEmpty(tag))
				{
					selectedHardwares = hardwares.Where(x => x.Tags != null && x.Tags.Contains(tag)).Except(alreadyAddedHardwares);
				}
				else
				{
					selectedHardwares = hardwares.Where(x => x.Tags == null || x.Tags.Count == 0);
				}

				if (selectedHardwares != null && selectedHardwares.Count() != 0)
				{
					List<Common.Hardware> list = selectedHardwares.ToList();
					model.HardwareTagged.Add(tag, list);
					alreadyAddedHardwares.AddRange(list);
				}
			}

			return View(model);
		}

		public ActionResult CategoryIndex()
		{
			List<Common.Category> categories = Common.Hardware.RetrieveCategoriesAll();

			var viewModel = new StoreCategoryIndexViewModel
			{
				NumberOfCategories = categories.Count,
				Categories = categories
			};

			return View(viewModel);
		}

		public ActionResult Details(int id)
		{
			var hardware = Common.Hardware.RetrieveByCommodityID(id);
			if (hardware == null)
				throw new HttpException(404, "Page not found");

			return View(hardware);
		}

		public ActionResult Index()
		{
			var viewModel = new HardwareIndexViewModel
			{
				Hardwares = Common.Hardware.RetrieveHardwaresByCategory()
			};

			return View(viewModel);
		}

		[Authorize(Roles = Globals.AdministratorRoleName)]
		public ActionResult Create()
		{
			var viewModel = new HardwareEditViewModel
			{
				Categories = Common.Category.RetrieveAll(),
				Hardware = new Common.Hardware()
			};

			return View(viewModel);
		}

		[Authorize(Roles = Globals.AdministratorRoleName)]
		[HttpPost]
		public ActionResult Create(Common.Hardware hardware)
		{
			try
			{
				if (!ModelState.IsValid)
					throw new ArgumentException("Ошибка при заполнении полей для: Hardware!");

				hardware.Create(HttpContext.User.Identity.Name);
				return RedirectToAction("Index");
			}
			catch (Exception e)
			{
				var viewModel = new HardwareEditViewModel
				{
					Categories = Common.Category.RetrieveAll(),
					Hardware = hardware,
					Message = e.Message
				};

				return View(viewModel);
			}
		}

		[Authorize(Roles = Globals.AdministratorRoleName)]
		public ActionResult Edit(int id)
		{
			var hardware = Common.Hardware.RetrieveByCommodityID(id);
			if (hardware == null)
				throw new HttpException(404, "Page not found");

			var viewModel = new HardwareEditViewModel
			{
				Categories = Common.Category.RetrieveAll(),
				Hardware = hardware
			};

			return View(viewModel);
		}

		[Authorize(Roles = Globals.AdministratorRoleName)]
		[HttpPost]
		public ActionResult Edit(int id, FormCollection collection)
		{
			var hardware = Common.Hardware.RetrieveByCommodityID(id);
			if (hardware == null)
				throw new HttpException(404, "Page not found");

			try
			{
				if (!ModelState.IsValid)
					throw new ArgumentException("Ошибка при заполнении полей для: Hardware!");

				UpdateModel(hardware, "Hardware");
				hardware.Update(HttpContext.User.Identity.Name);
				return Redirect(Url.RouteUrl(new { action = "Index" }) + "#id" + id);
			}
			catch (Exception e)
			{
				var viewModel = new HardwareEditViewModel
				{
					Hardware = hardware,
					Categories = Common.Category.RetrieveAll(),
					Message = e.Message
				};

				return View(viewModel);
			}
		}

		[Authorize(Roles = Globals.AdministratorRoleName)]
		public ActionResult Delete(int hardwareID)
		{
			var hardware = Common.Hardware.RetrieveByHardwareID(hardwareID);
			if (hardware == null)
				throw new HttpException(404, "Page not found");
			var viewModel = new HardwareRemoveViewModel()
			{
				Hardware = hardware
			};

			return View(viewModel);
		}

		[Authorize(Roles = Globals.AdministratorRoleName)]
		[HttpPost]
		public ActionResult Delete(int hardwareID, FormCollection collection)
		{
			var hardware = Common.Hardware.RetrieveByHardwareID(hardwareID);
			if (hardware == null)
				throw new HttpException(404, "Page not found");

			try
			{
				if (!ModelState.IsValid)
					throw new ArgumentException("Ошибка при заполнении полей для: Hardware!");

				Common.Hardware.Delete(hardwareID);
				return RedirectToAction("Index");
			}
			catch (Exception e)
			{
				var viewModel = new HardwareRemoveViewModel()
				{
					Hardware = hardware,
					Message = e.Message
				};

				return View(viewModel);
			}
		}

		[Authorize(Roles = Globals.AdministratorRoleName)]
		[AcceptVerbs(HttpVerbs.Get)]
		public ActionResult ExportXml()
		{
			string filename = "Hardwares.xml";
			string contentDisposition = String.Format("attachment; filename={0};", filename);

			Response.Clear();
			Response.ContentType = "application/xml";
			Response.AppendHeader("Content-Disposition", contentDisposition);

			XmlDocument doc = IntellectShop.Common.Hardware.ExportToXml();
			using (MemoryStream outStream = new MemoryStream())
			{
				using (XmlTextWriter writer = new XmlTextWriter(outStream, Encoding.UTF8))
				{
					writer.Formatting = Formatting.Indented;
					writer.Indentation = 1;
					writer.IndentChar = '\t';
					doc.Save(writer);

					return File(outStream.ToArray(), "application/xml");
				}
			}
		}
	}
}
